package com.xinshujia.config.authentication.provider;

import com.xinshujia.config.authentication.service.MyPhoneDetailsService;
import com.xinshujia.config.authentication.token.MyPhoneAuthenticationToken;
import com.xinshujia.entity.UserEntity;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

/**
 * *************************************
 * *   @author: 野狼上校               **
 * *   @since: 2024-07-16 13:30       **
 * *   @version: 1.0                  **
 * *************************************
 * <p>
 * 手机号码登录 认证处理器
 */
@Component
public class MyPhoneAuthenticationProvider implements AuthenticationProvider {

    private final MyPhoneDetailsService myPhoneDetailsService;

    public MyPhoneAuthenticationProvider(MyPhoneDetailsService myPhoneDetailsService) {
        this.myPhoneDetailsService = myPhoneDetailsService;
    }


    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 1. 获取用户输入的信息
        MyPhoneAuthenticationToken myPhoneAuthenticationToken = (MyPhoneAuthenticationToken) authentication;
        String phone = (String) myPhoneAuthenticationToken.getPrincipal();
        String password = (String) myPhoneAuthenticationToken.getCredentials();

        // 2. 根据phone从数据库中查询用户信息
        UserEntity userEntity = (UserEntity) myPhoneDetailsService.loadUserByUsername(phone);
        if (ObjectUtils.isEmpty(userEntity)) {
            throw new BadCredentialsException("账号不存在");
        }
        // 3. 验证密码是否正确(使用DelegatingPasswordEncode加密方案)
        PasswordEncoder delegatingPasswordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        boolean matches = delegatingPasswordEncoder.matches(authentication.getCredentials().toString(), userEntity.getPassword());
        if (!matches) {
            throw new BadCredentialsException("密码不正确");
        }
        // 4. 把用户信息封装到PhoneAuthenticationToken中
        MyPhoneAuthenticationToken phoneAuthenticationTokenFull = new MyPhoneAuthenticationToken(userEntity, password, userEntity.getAuthorities());
        phoneAuthenticationTokenFull.setDetails(myPhoneAuthenticationToken.getDetails());
        return phoneAuthenticationTokenFull;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return MyPhoneAuthenticationToken.class.isAssignableFrom(authentication);
    }
}